#include <iostream>
#include <mutex>

#include "server.h"
#include "io_context_pool.h"
#include "singleton.hpp"

Server::Server(IOContext& io_context, const uint16_t port)
:_io_context(io_context)
,_port(port)
,_acceptor(io_context, Tcp::endpoint(Tcp::v4(), port))
{
    start_accept();
}

Server::~Server()
{
    
}


void Server::start_accept()
{
    auto& ioc = Singleton<IOContextPool>::GetInstance()->get_io_context();
    Session::ptr session = std::make_shared<Session>(ioc, this);

    _acceptor.async_accept(session->socket(), [this, session](const boost::system::error_code& error){
        this->handle_accept(session, error);
    });

}

void Server::handle_accept(Session::ptr session, const boost::system::error_code& error)
{
    if(error)
    {
        delete_session(session->uuid());
        std::cout << "accept error: " << error.message() << std::endl;
        return;
    }

    session->start();

    {
        std::unique_lock<std::mutex> lock(_sessions_lock);
        _sessions.insert(std::make_pair(session->uuid(), session));
    }

    start_accept();
}   

void Server::delete_session(const std::string& id)
{
    auto find = _sessions.find(id);
    if(find != _sessions.end())
    {
        std::unique_lock<std::mutex> lock(_sessions_lock);
        _sessions.erase(find);
    }
}


